package com.wash.shoes.controller.pc;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.wash.shoes.common.enums.FactoryServiceTypeEnum;
import com.wash.shoes.common.enums.FactoryShelvesStatusEnum;
import com.wash.shoes.common.enums.FactoryStatusEnum;
import com.wash.shoes.common.enums.FactoryTypeEnum;
import com.wash.shoes.entity.BrandPo;
import com.wash.shoes.entity.FactoryAreaConfigPo;
import com.wash.shoes.entity.FactoryPo;
import com.wash.shoes.entity.FactoryshelvesPo;
import com.wash.shoes.request.BatchFactoryRequest;
import com.wash.shoes.request.FactoryDispatchRequest;
import com.wash.shoes.request.FactoryQueryRequest;
import com.wash.shoes.request.FactoryUpdateRequest;
import com.wash.shoes.resp.FactoryAreaConfigResp;
import com.wash.shoes.resp.FactoryShelveResp;
import com.wash.shoes.service.BrandService;
import com.wash.shoes.service.FactoryAreaConfigService;
import com.wash.shoes.service.FactoryService;
import com.wash.shoes.service.FactoryShelvesService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Api(tags = {"工厂管理"})
@RequestMapping("/factory")
@RequiredArgsConstructor
public class FactoryController {

    private final FactoryService factoryService;
    private final FactoryAreaConfigService factoryAreaConfigService;

    private final BrandService brandService;

    @Autowired
    private FactoryShelvesService factoryShelvesService;

/*    private static String getConvertBrand(List<FactoryAreaConfigPo> factoryAreaConfigPoList,
        Map<String, BrandPo> brandPoMap) {
        List<String> list = factoryAreaConfigPoList.stream().map(FactoryAreaConfigPo::getBrandId)
            .filter(Objects::nonNull).distinct().collect(Collectors.toList());
        StringBuffer str = new StringBuffer();
        for (String brandId : list) {
            BrandPo brandPo = brandPoMap.get(brandId);
            if (Objects.nonNull(brandPo)) {
                str.append("," + brandPo.getBrandName());
            }
        }
        return str.length() > 0 ? str.substring(0, str.length()) : "";
    }*/

    private static String getConvertBrand(List<FactoryAreaConfigPo> factoryAreaConfigPoList,
                                          Map<String, BrandPo> brandPoMap) {
        return factoryAreaConfigPoList.stream()
                .map(FactoryAreaConfigPo::getBrandId)
                .filter(Objects::nonNull)
                .distinct()
                .map(brandPoMap::get)
                .filter(Objects::nonNull)
                .map(BrandPo::getBrandName)
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
    }

    private static String getConvertArea(List<FactoryAreaConfigPo> factoryAreaConfigPoList) {
        List<String> provinceAndCityList = factoryAreaConfigPoList.stream()
                .map(factoryAreaConfigPo -> factoryAreaConfigPo.getProvinces() + " " + factoryAreaConfigPo.getCity())
                .distinct().collect(Collectors.toList());

        /*    StringBuffer str = new StringBuffer();
        for (String provinceAndCity : provinceAndCityList) {
            str.append("," + provinceAndCity);
        }*/
        StringBuffer str = new StringBuffer(StringUtil.join(provinceAndCityList, ","));
        return str.length() > 0 ? str.substring(0, str.length()) : "";
    }

    private static String getConvertCode(List<FactoryAreaConfigPo> factoryAreaConfigPoList) {

        StringBuffer str = new StringBuffer();
        for (FactoryAreaConfigPo factoryAreaConfigPo : factoryAreaConfigPoList) {
            str.append("," + factoryAreaConfigPo.getCode());
        }
        return str.substring(0, str.length());

    }

    @PostMapping("/list")
    @ApiOperation("工厂列表")
    public R<Object> list(@RequestBody @Valid FactoryQueryRequest factoryQueryRequest) {

        return R.ok(getFactoryListToPage(factoryQueryRequest));
    }

    @ApiOperation("工厂类型")
    @GetMapping("/getFactoryType")
    public R getFactoryType() {
        return R.ok(FactoryTypeEnum.getAllFactoryType());
    }

    @ApiOperation("服务类型")
    @GetMapping("/getServiceType")
    public R getServiceType() {
        return R.ok(FactoryServiceTypeEnum.getAllFactoryType());
    }

    @ApiOperation("工厂列表-带货架信息")
    @PostMapping("/getFactoryWithShelve")
    public R<IPage<?>>
    getFactoryWithShelve(@RequestBody @Valid FactoryQueryRequest factoryQueryRequest) {
        IPage<FactoryPo> page = factoryService.page(factoryQueryRequest.toPage(),
                new LambdaQueryWrapper<FactoryPo>()
                        .like(StringUtils.isNotEmpty(factoryQueryRequest.getFactoryName()), FactoryPo::getFactoryName,
                                factoryQueryRequest.getFactoryName())
                        .like(StringUtils.isNotEmpty(factoryQueryRequest.getFactoryManager()), FactoryPo::getFactoryManager,
                                factoryQueryRequest.getFactoryManager())
                        .in(Objects.nonNull(factoryQueryRequest.getFactoryServiceType()), FactoryPo::getServiceType,
                                factoryQueryRequest.getFactoryServiceType())
                        .eq(Objects.nonNull(factoryQueryRequest.getStatus()), FactoryPo::getStatus,
                                factoryQueryRequest.getStatus()));
        List data1 = new ArrayList();
        page.getRecords().stream().forEach(e -> {
            // 获取这个工厂货架信息
            List<FactoryshelvesPo> data = factoryShelvesService
                    .list(new LambdaQueryWrapper<FactoryshelvesPo>().eq(FactoryshelvesPo::getFactoryId, e.getId())
                            .eq(FactoryshelvesPo::getStatus, FactoryShelvesStatusEnum.ONLINE));
            List data2 = new ArrayList();
            for (FactoryshelvesPo factoryshelvesPo : data) {
                FactoryShelveResp.FactoryShelveRecord factoryShelveRecord = new FactoryShelveResp.FactoryShelveRecord();
                factoryShelveRecord.setPrefix(factoryshelvesPo.getPrefix());
                factoryShelveRecord.setCapacity(factoryshelvesPo.getCapacity());
                factoryShelveRecord.setId(factoryshelvesPo.getId());
                // 货架
                data2.add(factoryShelveRecord);
            }
            FactoryShelveResp factoryShelveResp = new FactoryShelveResp();
            factoryShelveResp.setFactoryId(e.getId());
            factoryShelveResp.setFactoryName(e.getFactoryName());
            factoryShelveResp.setData(data2);
            data1.add(factoryShelveResp);
        });
        page.setRecords(data1);
        // factoryService.getFactoryWithShelve();
        return R.ok(page);
    }

    @ApiOperation("工厂保存")
    @PostMapping("/saveOrUpdate")
    public R<Object> add(@RequestBody @Valid FactoryPo factoryPo) {
        if (Objects.isNull(factoryPo.getId())) {
            factoryPo.setStatus(FactoryStatusEnum.NORMAL);
        }
        return R.ok(factoryService.saveOrUpdate(factoryPo));
    }

    @PostMapping("/updateStatus")
    @ApiOperation("工厂状态修改")
    public R updateStatus(@RequestBody @Valid FactoryUpdateRequest factoryUpdateRequest) {
        FactoryPo factoryPo = new FactoryPo();
        factoryPo.setStatus(factoryUpdateRequest.getStatus());
        //工厂状态是停用的时候就把工厂覆盖的范围删除调
        if (factoryUpdateRequest.getStatus() == FactoryStatusEnum.STOP) {
            factoryPo.setUpdateTime(new Date());
            factoryAreaConfigService.remove(new LambdaQueryWrapper<FactoryAreaConfigPo>().eq(FactoryAreaConfigPo::getFactoryId, factoryUpdateRequest.getId()));
        }
        return R.ok(factoryService.update(factoryPo,
                new LambdaQueryWrapper<FactoryPo>().eq(FactoryPo::getId, factoryUpdateRequest.getId())));
    }

    @PostMapping("/batchDeleteFactory")
    @ApiOperation("批量删除工厂")
    public R batchDeleteFactory(@RequestBody @Valid BatchFactoryRequest batchFactoryRequest) {
        factoryService.update(new LambdaUpdateWrapper<FactoryPo>().in(FactoryPo::getId, batchFactoryRequest.getIdList())
                .set(FactoryPo::getStatus, FactoryStatusEnum.STOP));
        /*        factoryShelvesService.remove(new LambdaQueryWrapper<FactoryshelvesPo>().in(FactoryshelvesPo::getFactoryId,
            batchFactoryRequest.getIdList()));*/
        factoryAreaConfigService.remove(new LambdaQueryWrapper<FactoryAreaConfigPo>().in(FactoryAreaConfigPo::getFactoryId, batchFactoryRequest.getIdList()));
        return R.ok();
    }

    @ApiOperation("工厂详情")
    @GetMapping("/getFactoryDetailById")
    public R getFactoryDetailById(String id) {
        return R.ok(factoryService.getById(id));
    }

    // TODO 给工厂派单,指定工厂接某些城市的订单
    @ApiOperation("派单配置")
    @PostMapping("/dispatch")
    public R<Boolean> dispatch(@RequestBody @Valid FactoryDispatchRequest factoryDispatchRequest) {
        return R.ok(
                factoryAreaConfigService.dispatch(factoryDispatchRequest.getFactoryId(), factoryDispatchRequest.getData()));
    }

    @GetMapping("/getFactoryDispatchConfig")
    @ApiOperation("获取工厂派单配置")
    @ApiImplicitParam(name = "factoryId", value = "工厂id", required = true, dataType = "String")
    public R getFactoryDispatchConfig(@NotNull(message = "工厂id不能为空") String factoryId) {
        List<FactoryAreaConfigPo> factoryAreaConfigPoList =
                factoryAreaConfigService.list(new LambdaQueryWrapper<FactoryAreaConfigPo>()
                        .eq(FactoryAreaConfigPo::getFactoryId, factoryId).eq(FactoryAreaConfigPo::getStatus, 1));

        return R.ok(buildFactoryAreaConfigResp(factoryAreaConfigPoList));
    }

    /**
     * 导出【请填写功能名称】列表
     */
    // @PreAuthorize("@ss.hasPermi('system:factory:export')")
    // @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
    @ApiOperation("导出工厂为excel表格")
    @PostMapping("/export")
    public void export(HttpServletResponse response, FactoryQueryRequest factoryQueryRequest) {
        IPage<FactoryPo> page = getFactoryListToPage(factoryQueryRequest);
        List<FactoryPo> list = page.getRecords();
        ExcelUtil<FactoryPo> util = new ExcelUtil<FactoryPo>(FactoryPo.class);
        util.exportExcel(response, list, "工厂列表导出");
    }

    private IPage<FactoryPo> getFactoryListToPage(FactoryQueryRequest factoryQueryRequest) {
        IPage<FactoryPo> page = factoryService.page(factoryQueryRequest.toPage(),
                new LambdaQueryWrapper<FactoryPo>()
                        .like(StringUtils.isNotEmpty(factoryQueryRequest.getFactoryName()), FactoryPo::getFactoryName,
                                factoryQueryRequest.getFactoryName())
                        .like(StringUtils.isNotEmpty(factoryQueryRequest.getFactoryManager()), FactoryPo::getFactoryManager,
                                factoryQueryRequest.getFactoryManager())
                        .like(Objects.nonNull(factoryQueryRequest.getFactoryServiceType()), FactoryPo::getServiceType,
                                factoryQueryRequest.getFactoryServiceType())
                        .eq(Objects.nonNull(factoryQueryRequest.getStatus()), FactoryPo::getStatus, factoryQueryRequest.getStatus()));
        List<FactoryPo> factoryPo = page.getRecords();
        List<BrandPo> brandPoList = brandService.list(new LambdaQueryWrapper<BrandPo>().eq(BrandPo::getStatus, 1));
        Map<String, BrandPo> brandPoMap =
                brandPoList.stream().collect(Collectors.toMap(BrandPo::getId, brandPo -> brandPo));
        for (FactoryPo po : factoryPo) {
            String factoryId = po.getId();
            List<FactoryAreaConfigPo> factoryAreaConfigPoList =
                    factoryAreaConfigService.list(new LambdaQueryWrapper<FactoryAreaConfigPo>()
                            .eq(FactoryAreaConfigPo::getFactoryId, factoryId).eq(FactoryAreaConfigPo::getStatus, 1));
            if (CollectionUtils.isEmpty(factoryAreaConfigPoList)) {
                continue;
            }
            po.setCoveringBrand(getConvertBrand(factoryAreaConfigPoList, brandPoMap));
            po.setCoveringArea(getConvertArea(factoryAreaConfigPoList));
            po.setCode(getConvertCode(factoryAreaConfigPoList));
        }
        return page;
    }

    ;

    private FactoryAreaConfigResp buildFactoryAreaConfigResp(List<FactoryAreaConfigPo> factoryAreaConfigPoList) {
        FactoryAreaConfigResp factoryAreaConfigResp = new FactoryAreaConfigResp();
        factoryAreaConfigResp.setBrandIdList(factoryAreaConfigPoList.stream().map(FactoryAreaConfigPo::getBrandId)
                .distinct().collect(Collectors.toList()));
        factoryAreaConfigResp.setCodeList(
                factoryAreaConfigPoList.stream().map(FactoryAreaConfigPo::getCode).distinct().collect(Collectors.toList()));
        return factoryAreaConfigResp;
    }

}
